//
//  calculator.c
//  TestPrizeCaculator
//
//  Created by 苏宇靖 on 2018/7/5.
//  Copyright © 2018年 Zeeging Tech. All rights reserved.
//

#include "calculator.h"
//const int EugeneSu=1;
//int SYJ(int mm){
//    return 0;
//}

const GGType _ggtype[]= {
    {"1*1"  ,{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 1, 1, 1},
    {"2*1"  ,{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 2, 2, 1},
    {"3*1"  ,{0,0,1,0,0,0,0,0,0,0,0,0,0,0,0}, 3, 3, 1},
    {"4*1"  ,{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, 4, 4, 1},
    {"5*1"  ,{0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, 5, 5, 1},
    {"6*1"  ,{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}, 6, 6, 1},
    {"7*1"  ,{0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}, 7, 7, 1},
    {"8*1"  ,{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0}, 8, 8, 1},
    {"9*1"  ,{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0}, 9, 9, 1},
    {"10*1" ,{0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}, 10, 10, 1},
    {"11*1" ,{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, 11, 11, 1},
    {"12*1" ,{0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}, 12, 12, 1},
    {"13*1" ,{0,0,0,0,0,0,0,0,0,0,0,0,1,0,0}, 13, 13, 1},
    {"14*1" ,{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, 14, 14, 1},
    {"15*1" ,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, 15, 15, 1},
    {"2*3"  ,{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 2, 1, 3},
    {"3*6"  ,{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 3, 1, 16},
    {"3*7"  ,{1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, 3, 1, 7},
    {"4*10" ,{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 4, 1, 10},
    {"4*14" ,{1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, 4, 1, 14},
    {"4*15" ,{1,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, 4, 1, 15},
    {"5*15" ,{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 5, 1, 15},
    {"5*25" ,{1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, 5, 1, 25},
    {"5*30" ,{1,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, 5, 1, 30},
    {"5*31" ,{1,1,1,1,1,0,0,0,0,0,0,0,0,0,0}, 5, 1, 31},
    {"6*21" ,{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 6, 1, 21},
    {"6*41" ,{1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, 6, 1, 41},
    {"6*56" ,{1,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, 6, 1, 56},
    {"6*62" ,{1,1,1,1,1,0,0,0,0,0,0,0,0,0,0}, 6, 1, 62},
    {"6*63" ,{1,1,1,1,1,1,0,0,0,0,0,0,0,0,0}, 6, 1, 63},
    {"7*127",{1,1,1,1,1,1,1,0,0,0,0,0,0,0,0}, 7, 1, 127},
    {"8*255",{1,1,1,1,1,1,1,1,0,0,0,0,0,0,0}, 8, 1, 255},
    {"3*3"  ,{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 3, 2, 3},
    {"3*4"  ,{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, 3, 2, 4},
    {"4*6"  ,{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 4, 2, 6},
    {"4*11" ,{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, 4, 2, 11},
    {"5*10" ,{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 5, 2, 10},
    {"5*20" ,{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, 5, 2, 20},
    {"5*26" ,{0,1,1,1,1,0,0,0,0,0,0,0,0,0,0}, 5, 2, 26},
    {"6*15" ,{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 6, 2, 15},
    {"6*35" ,{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, 6, 2, 35},
    {"6*50" ,{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, 6, 2, 50},
    {"6*57" ,{0,1,1,1,1,1,0,0,0,0,0,0,0,0,0}, 6, 2, 57},
    {"7*120",{0,1,1,1,1,1,1,0,0,0,0,0,0,0,0}, 7, 2, 120},
    {"8*247",{0,1,1,1,1,1,1,1,0,0,0,0,0,0,0}, 8, 2, 247},
    {"4*4"  ,{0,0,1,0,0,0,0,0,0,0,0,0,0,0,0}, 4, 3, 4},
    {"4*5"  ,{0,0,1,1,0,0,0,0,0,0,0,0,0,0,0}, 4, 3, 5},
    {"5*16" ,{0,0,1,1,1,0,0,0,0,0,0,0,0,0,0}, 5, 3, 16},
    {"6*20" ,{0,0,1,0,0,0,0,0,0,0,0,0,0,0,0}, 6, 3, 20},
    {"6*42" ,{0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, 6, 3, 42},
    {"5*5"  ,{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, 5, 4, 5},
    {"5*6"  ,{0,0,0,1,1,0,0,0,0,0,0,0,0,0,0}, 5, 4, 6},
    {"6*22" ,{0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}, 6, 4, 22},
    {"7*35" ,{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, 7, 4, 35},
    {"8*70" ,{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, 8, 4, 70},
    {"6*6"  ,{0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, 6, 5, 6},
    {"6*7"  ,{0,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, 6, 5, 7},
    {"7*21" ,{0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, 7, 5, 21},
    {"8*56" ,{0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, 8, 5, 56},
    {"7*7"  ,{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}, 7, 6, 7},
    {"7*8"  ,{0,0,0,0,0,1,1,0,0,0,0,0,0,0,0}, 7, 6, 8},
    {"8*28" ,{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}, 8, 6, 28},
    {"8*8"  ,{0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}, 8, 7, 8},
    {"8*9"  ,{0,0,0,0,0,0,1,1,0,0,0,0,0,0,0}, 8, 7, 9}
};
const int _ggtype_size = sizeof(_ggtype)/sizeof(_ggtype[0]);

const int EugeneSu=1;
int SYJ(int mm){
    return 0;
}
const int _score_jz[][2] = {
    {1,0},{2,0},{2,1},{3,0},{3,1},{3,2},{4,0},{4,1},{4,2},{5,0},{5,1},{5,2},{6,0},{999,0}, //  §∆‰À¸£¨6:0£¨∞Î≥°≤ªƒ‹Œ™∏∫
    {0,0},{1,1},{2,2},{3,3},{999,999},
    {0,1},{0,2},{1,2},{0,3},{1,3},{2,3},{0,4},{1,4},{2,4},{0,5},{1,5},{2,5},{0,6},{0,999}  // ∏∫∆‰À¸£¨0:6£¨∞Î≥°≤ªƒ‹Œ™ §
};
const int _score_jz_size = sizeof(_score_jz)/sizeof(_score_jz[0]);


const int _score_jl[][3] = {
    {0, 1, 5}, {0, 6, 10}, {0, 11, 15}, {0, 16, 20}, {0, 21, 25}, {0, 26, 999},
    {1, 1, 5}, {1, 6, 10}, {1, 11, 15}, {1, 16, 20}, {1, 21, 25}, {1, 26, 999}
};
const int _score_jl_size = sizeof(_score_jl)/sizeof(_score_jl[0]);

Project  _pro;      // ∑Ω∞∏
Bet _bet;           // Õ∂◊¢ƒ⁄»›

// ∑÷∏Ó
int split(char *str, char delim, char *res[MAX_SPLIT])
{
    int cnt;
    char *p;
    for(p=str, cnt=0; *str != 0x00 && cnt < MAX_SPLIT; ++str) {
        if (*str == delim) {
            *str=0x00;
            if (p != str) {
                res[cnt++] = p;
            }
            p=str+1;
        }
    }
    
    if (p != str) {
        res[cnt++] = p;
    }
    
    return cnt;
}

int unpack(char *ggtype, char *content)
{
    int ret;
    ret = unpack_ggtype(ggtype);
    if (ret != 0) {
        return ret;
    }
    
    ret = unpack_content(content);
    if (ret !=0) {
        return ret;
    }
    
    return 0;
}

int unpack_ggtype(char *str)
{
    char *ggtype[MAX_SPLIT];
    int size;
    int i,j;
    
    size = split(str, ';', ggtype);
    if (size < 1 || size >= MAX_GGTYPE) {
        return ERR_UNPACK_GGTYPE;
    }
    
    for(i=0; i<size; ++i) {
        for (j=0; j<_ggtype_size; ++j) {
            if (strcmp(ggtype[i], _ggtype[j].name) == 0) {
                _pro.ggtype[_pro.ggtype_size++] = _ggtype[j];
                break;
            }
        }
        
        if (j == _ggtype_size) {
            return ERR_UNKNOWN_GGTYPE;
        }
    }
    
    return 0;
}

int unpack_content(char *str)
{
    char *match[MAX_SPLIT] = {0};
    int size=0;
    int i, ret;
    size = split(str, ';', match);
    if (size < 1 || size >= MAX_MATCH) {
        return ERR_UNPACK_MATCH;
    }
    
    if (size >= MAX_MATCH) {
        return ERR_UNPACK_MATCH;
    }
    
    for(i=0; i<size; ++i) {
        ret = unpack_match(match[i]);
        if (ret != 0) {
            return ret;
        }
        ++_pro.match_size;
    }
    return 0;
}

int unpack_match(char *str)
{
    char *item[MAX_SPLIT] = {0};
    int size, ret;
    Match *match;
    
    size = split(str, '|', item);
    if (size != 4) {
        return ERR_UNPACK_SELECT;
    }
    
    match = &_pro.match[_pro.match_size];
    strcpy(match->id, item[0]);
    match->extra_score = atof(item[1]);
    match->fixed = atoi(item[2]);
    if (match->fixed == 1) {
        ++_pro.fixed_size;
    }
    ret = unpack_select(item[3]);
    if (ret != 0) {
        return ret;
    }
    
    return 0;
}

int unpack_select(char *str)
{
    char *s1[MAX_SPLIT] = {0};
    int i, j, k, size1;
    Match *match = &_pro.match[_pro.match_size];
    
    size1 = split(str, '/', s1);
    if (size1 < 1 || size1 >= MAX_SELECT) {
        return ERR_UNPACK_SELECT;
    }
    
    for(i=0; i<size1; ++i) {
        Select *sel = &match->sel[match->sel_size];
        sel->match = match;
        sel->extra_score = match->extra_score;
        sprintf(sel->raw, "%s#%s", match->id, s1[i]);
        
        char *s2[MAX_SPLIT] = {0};
        int size2 = 0;
        size2 = split(s1[i], '#', s2);
        if (size2 != 3) {
            return ERR_UNPACK_SELECT;
        }
        
        sel->odds = atof(s2[2]);
        int playid = atoi(s2[0]);
        if (_pro.lot == LOT_JCZQ) {
            switch(playid) {
                case 354:
                    sel->playid = JZ_SPF;
                    break;
                case 269:
                    sel->playid = JZ_RQSPF;
                    break;
                case 271:
                    sel->playid = JZ_BF;
                    break;
                case 270:
                    sel->playid = JZ_ZJQ;
                    break;
                case 272:
                    sel->playid = JZ_BQC;
                    break;
                default:
                    return ERR_UNKNOWN_PLAY;
            }
        } else if (_pro.lot == LOT_JCLQ) {
            switch(playid) {
                case 274:
                    sel->playid = JL_SF;
                    break;
                case 275:
                    sel->playid = JL_RFSF;
                    break;
                case 276:
                    sel->playid = JL_SFC;
                    break ;
                case 277:
                    sel->playid = JL_DXF;
                    break;
                default:
                    return ERR_UNKNOWN_PLAY;
            }
        } else if (_pro.lot == LOT_BJDC) {
            switch(playid) {
                case 34:
                    sel->playid = BD_RQSPF;
                    break;
                case 407:
                    sel->playid = BD_SFGG;
                    break;
                case 40:
                    sel->playid = BD_ZJQ;
                    break;
                case 41:
                    sel->playid = BD_SXDS;
                    break;
                case 42:
                    sel->playid = BD_BF;
                    break;
                case 51:
                    sel->playid = BD_BQC;
                    break;
                default:
                    return ERR_UNKNOWN_PLAY;
            }
        } else {
            return ERR_LOTTERY;
        }
        
        if (sel->playid == JZ_BF) {
            char *bf[MAX_PLAY] = {0};
            if (split(s2[1], ':', bf) != 2) {
                return ERR_UNPACK_SELECT;
            }
            sel->home_score = atof(bf[0]);
            sel->away_score = atof(bf[1]);
            
            if (sel->home_score > sel->away_score) {
                sel->select = 3;
            } else if (sel->home_score == sel->away_score) {
                sel->select = 1;
            } else {
                sel->select = 0;
            }
        } else {
            sel->select = atoi(s2[1]);
        }
        ++match->sel_size;
        
        // ∞——°œÓ∞¥ÕÊ∑®∑÷¿‡
        for(j=0; j<match->play_size; ++j) {
            if (match->play[j][0]->playid == sel->playid) {
                for(k=0; match->play[j][k] != NULL; ++k);
                match->play[j][k] = sel;
                break;
            }
        }
        if (j == match->play_size) {
            match->play[match->play_size++][0] = sel;
        }
        
    }
    
    return 0;
}


int calc_max_odds_comb()
{
    int i, j, k, ret;
    for(i=0; i<_pro.match_size; ++i) {
        Match *match = &_pro.match[i];
        if (match->play_size == 1) {
            // ∑«ªÏÕ∂±»»¸£¨÷±Ω”’“≥ˆ◊Ó¥Ûµƒ≈‚¬ º¥ø…
            Select *sel = &match->sel[0];
            for(j=1; j<match->sel_size; ++j) {
                if (match->sel[j].odds > sel->odds) {
                    sel = &match->sel[j];
                }
            }
            sel->ismax = 1;
        } else {
            int size;
            if (_pro.lot == LOT_JCZQ) {
                size = _score_jz_size;
            } else if (_pro.lot == LOT_JCLQ) {
                size = _score_jl_size;
            } else { // ±±æ©µ•≥°≤ª÷ß≥÷ªÏÕ∂£¨µ±±±µ•ø™ º÷ß≥÷ªÏÕ∂ «£¨“™‘ˆº”∂‘±±µ•∏˜ÕÊ∑®œ‡»›–‘µƒ¥¶¿Ì
                return ERR_LOTTERY;
            }
            
            OddsComb comb1;
            memset(&comb1, 0x00, sizeof(comb1));
            for (j=0; j<size; ++j) {
                OddsComb comb2;
                memset(&comb2, 0x00, sizeof(comb2));
                for(k=0; k<match->sel_size; ++k) {
                    Select *sel = &match->sel[k];
                    if (_pro.lot == LOT_JCZQ) {
                        ret = check_compatible_jczq(j, sel);
                    } else {
                        ret = check_compatible_jclq(j, sel);
                    }
                    if (ret == 1) {
                        int l;
                        // ºÏ≤È”–√ª”–œ‡Õ¨ÕÊ∑®µƒ—°œÓ
                        // »Áπ˚”–£¨≈‚¬ ¥ÛÃÊªªµÙ£¨∑Ò‘Ú∂™∆˙
                        for(l=0; l<comb2.size; ++l) {
                            if (comb2.sel[l]->playid == sel->playid) {
                                if (comb2.sel[l]->odds < sel->odds) {
                                    comb2.odds -= comb2.sel[l]->odds;
                                    comb2.odds += sel->odds;
                                    comb2.sel[l] = sel;
                                }
                                break;
                            }
                        }
                        // »Áπ˚√ª”–œ‡Õ¨ÕÊ∑®£¨º”µΩ◊È∫œ¿Ô
                        if (l == comb2.size) {
                            comb2.sel[comb2.size++] = sel;
                            comb2.odds += sel->odds;
                        }
                    }
                }
                if (comb1.odds < comb2.odds) {
                    comb1 = comb2;
                }
            }
            for (j=0; j<comb1.size; ++j) {
                comb1.sel[j]->ismax = 1;
            }
        }
    }
    
    return 0;
}

int check_compatible_jczq(int i, Select *select)
{
    double home = _score_jz[i][0];
    double away = _score_jz[i][1];
    if (select->playid == JZ_SPF) {
        if (home > away && select->select == 3) {
            return 1;
        } else if (home == away && select->select == 1) {
            return 1;
        } else if (home < away && select->select == 0) {
            return 1;
        }
        return 0;
    }
    
    if (select->playid == JZ_RQSPF) {
        if (home == 999 || away == 999) {   // ∆‰À¸±»∑÷Ãÿ ‚¥¶¿Ì
            
            if (home > away) {  //  §∆‰À¸
                // ø…ƒ‹≥ˆœ÷»√«Ú §
                if (select->select == 3) {
                    return 1;
                }
                
                // ÷˜∂”»√«Ú ø…ƒ‹≥ˆœ÷»√«Ú∆Ω
                if (select->select == 1 && select->extra_score < 0) {
                    return 1;
                }
                
                // ÷˜∂”»√∂‡«Ú ø…ƒ‹≥ˆœ÷»√«Ú∏∫
                if (select->select == 0 && select->extra_score < -1) {
                    return 1;
                }
                
            } else if (home == away) {  // ∆Ω∆‰À¸
                // øÕ∂”»√«Ú »√«Ú §
                if (select->select == 3 && select->extra_score > 0) {
                    return 1;
                }
                
                // ∆Ω∆‰À˚≤ªø…ƒ‹»√«Ú∆Ω
                
                // ÷˜∂”»√«Ú »√«Ú∏∫
                if (select->select == 0 && select->extra_score < 0) {
                    return 1;
                }
            } else if (home < away) {   // ∏∫∆‰À¸
                // øÕ»√∂‡«Ú ø…ƒ‹»√«Ú §
                if (select->select == 3 && select->extra_score > 1) {
                    return 1;
                }
                
                // øÕ∂”»√«Ú ø…ƒ‹≥ˆœ÷»√«Ú∆Ω
                if (select->select == 1 && select->extra_score > 0) {
                    return 1;
                }
                
                // ø…ƒ‹≥ˆœ÷»√«Ú∏∫
                if (select->select == 0) {
                    return 1;
                }
            }
            
        } else {
            if (select->extra_score > 0) {  // øÕ»√
                away -= select->extra_score;
            } else { // ÷˜»√
                home -= abs(select->extra_score);
            }
            
            if (home > away && select->select == 3) {
                return 1;
            } else if (home == away && select->select == 1) {
                return 1;
            } else if (home < away && select->select == 0) {
                return 1;
            }
        }
        
        return 0;
    }
    
    if (select->playid == JZ_BF) {
        
        if (home == 6 && away == 0) {       // 6:0 “™◊™ªª≥… §∆‰À¸
            home = 999;
        } else if (home == 0 && away == 6) { // 0:6 “™◊™ªª≥…∏∫∆‰À¸
            away = 999;
        }
        
        if (home == select->home_score && away == select->away_score) {
            return 1;
        }
        
        return 0;
    }
    
    if (select->playid == JZ_ZJQ) {
        if (home == 999 || away == 999) {
            //  §∆‰À¸°¢∏∫∆‰À¸ ± “™øº¬«6:0ªÚ0:6µƒ«Èøˆ
            if (home != away && select->select >=6) {
                return 1;
            }
            if (home == away && select->select == 7) {
                return 1;
            }
        } else if (home + away == select->select) {
            return 1;
        }
        return 0;
    }
    
    if (select->playid == JZ_BQC) {
        if (home > away ) { //  §
            // øÕ∂”√ª”–µ√∑÷£¨”Î § §ªÚ∆Ω §œ‡»›
            if (away == 0 && (select->select == 33 || select->select == 13)) {
                return 1;
            }
            
            // øÕ∂”µ√∑÷,”Î § §/∆Ω §/∏∫ §œ‡»›
            if (away != 0 && select->select%10 == 3) {
                return 1;
            }
        } else if (home == away) { // ∆Ω
            // 0:0 ÷ªø…ƒ‹”Î ∆Ω∆Ωœ‡»›
            if (home == 0 && select->select == 11) {
                return 1;
            }
            
            // ∑«0:0 ∫Õ §∆Ω/∏∫∆Ω/∆Ω∆Ωœ‡»›
            if (home !=0 && select->select%10 == 1) {
                return 1;
            }
        } else if (home < away) { // ∏∫
            // ÷˜∂”√ª”–µ√∑÷£¨”Î∏∫∏∫/∆Ω∏∫œ‡»›
            if (home == 0 && (select->select == 00 || select->select == 10)) {
                return 1;
            }
            
            // ÷˜∂”µ√∑÷,”Î∏∫∏∫/∆Ω∏∫/ §∏∫œ‡»›
            if (home != 0 && select->select%10 == 0) {
                return 1;
            }
        }
        
        return 0;
    }
    
    return 0;
}

int check_compatible_jclq(int i, Select *select)
{
    int team = _score_jl[i][0];
    double b = _score_jl[i][1];
    double e = _score_jl[i][2];
    
    //  §∏∫
    if (select->playid == JL_SF) {
        if (select->select == 3 && team == 0) {
            return 1;
        }
        if (select->select == 0 && team == 1) {
            return 1;
        }
    }
    
    // »√∑÷ §∏∫
    if (select->playid == JL_RFSF) {
        // ÷˜∂” §+÷˜∂” ‹»√∑÷+ µº ÷˜∂” §
        if (select->select == 3 && select->extra_score > 0 && team == 0) {
            return 1;
        }
        // ÷˜∂” §+÷˜∂”»√∑÷+ µº ÷˜∂” § »√∑÷–°”⁄µ»”⁄∑÷≤Ó◊Ó¥Û÷µºÊ»›
        if (select->select == 3 && select->extra_score < 0 && team == 0) {
            if (-1*select->extra_score <= e) {
                return 1;
            }
        }
        
        // øÕ∂” §+øÕ∂” ‹»√∑÷+ µº øÕ∂” §
        if (select->select == 0 && select->extra_score < 0 && team == 1) {
            return 1;
        }
        // øÕ∂” §+øÕ∂”»√∑÷+ µº øÕ∂” § »√∑÷–°”⁄µ»”⁄∑÷≤Ó◊Ó¥Û÷µºÊ»›
        if (select->select == 0 && select->extra_score > 0 && team == 1) {
            if (select->extra_score <= e) {
                return 1;
            }
        }
        
        // ÷˜∂” §+÷˜∂” ‹»√∑÷+ µº øÕ∂” § »√∑÷¥Û”⁄µ»”⁄∑÷≤Ó◊Ó–°÷µºÊ»›
        if (select->select == 3 && select->extra_score > 0 && team == 1) {
            if (select->extra_score >= b) {
                return 1;
            }
        }
        
        // øÕ∂” §+øÕ∂” ‹»√∑÷+ µº ÷˜∂” § »√∑÷¥Û”⁄µ»”⁄∑÷≤Ó◊Ó–°÷µºÊ»›
        if (select->select == 0 && select->extra_score < 0 && team == 0) {
            if (-1*select->extra_score >= b) {
                return 1;
            }
        }
        
        // ÷˜∂” §+÷˜∂”»√∑÷+ µº øÕ∂” §
        // øÕ∂” §+øÕ∂”»√∑÷+ µº ÷˜∂” §
        // ’‚¡Ω÷÷«Èøˆ≤ªºÊ»›
    }
    
    //  §∑÷≤Ó
    if (select->playid == JL_SFC) {
        if (select->select == i) {
            return 1;
        }
    }
    
    // ¥Û–°∑÷
    if (select->playid == JL_DXF) {
        return 1;
    }
    
    return 0;
}

// º∆À„Õ∂◊¢£¨ø…÷ÿ∏¥
int calc_bet_dupl()
{
    int i, ret;
    for(i=0; i<_pro.ggtype_size; ++i) {
        ret = calc_bet_dulp_1(i);
        if (ret != 0) {
            return ret;
        }
    }
    return 0;
}

// ø…÷ÿ∏¥◊¢ ˝º∆À„µ⁄“ª≤Ω
// ∞¥√ø◊¢µƒ»¸ ¬ ˝∂‘»¸ ¬Ω¯––◊È∫œ 3x1 »¸ ¬ ˝Œ™3
//////////////////////////////////////////////////////////////////////////
//∑«µ›πÈ µœ÷¥”a ˝◊È(n∏ˆ)÷–—°»°m∏ˆµƒ◊È∫œ≈≈¡–
// int b[]: ÷–µƒb[i] = 1 «±Ì æa[i]—°…œ£¨∑Ò‘Ú±Ì æ√ª”–—°…œ
//À„∑®µƒÀºœÎ£∫
//¿˚”√n∏ˆ0£¨1¿¥±Ì æ“ª÷÷◊È∫œ≈≈¡–°£œÒn = 5, m = 3,‘Ú
//≈≈¡–ø…“‘Œ™£∫
/*
 111<-00
 1101<-0
 11<-001
 1011<-0
 101<-01
 1<-0011
 0111<-0
 011<-01
 01<-011
 00111
 ∆‰÷–"<-"±Ì æº˝Õ∑”“±ﬂµƒ0∫Õ◊Û±ﬂµƒ1Ωªªª£¨ªπ“™∞—¥”’‚∏ˆΩªªªŒª÷√(º¥0µƒŒª÷√)∆”“±ﬂÀ˘”–µƒ1∂º∑≈‘⁄“ª∆£¨
 ≤¢«“ΩÙ∏˙‘⁄¥ÀŒª÷√∫Û√Ê£¨»ª∫Û‘⁄ «∆‰À¸µƒ0£¨»Áœ¬√Ê±‰ªª£∫
 11001--->10110
  ◊œ»’“µΩƒ«∏ˆΩªªªµ„:
 11001---->10101------->10 110
 ^                                   ^^
 Ωªªªµ„   Ωªªª∫Û    ∞—Ωªªªµ„∫Û√Êµƒ1∂ºΩÙ∑≈‘⁄À¸µƒ∫Û√Ê»•
 */
int calc_bet_dulp_1(int ggidx)
{
    Match *matchs[MAX_MATCH] = {0};
    int n = _pro.match_size;
    int m = _pro.ggtype[ggidx].matchs;
    int i, cnt=0, flag[MAX_MATCH] = {0}, ret;
    
    for(i=0; i<m; ++i) {
        flag[i] = 1;
        matchs[i] = &_pro.match[i];
    }
    
    ret = calc_bet_dulp_2(ggidx, matchs, m);
    if (ret != 0) {
        return ret;
    }
    
    do {
        cnt = 0;
        for(i=n-1; i>0; i--) {
            if (flag[i] == 0 && flag[i-1] == 1) { // …®√ËµΩ"10"
                break;
            }
            if (1 == flag[i]) {
                cnt++;  //Õ≥º∆1µƒ∏ˆ ˝
            }
        }
        if (i > 0) {
            int t = flag[i];
            flag[i] = flag[i-1];
            flag[i-1] = t;
            //”“±ﬂcnt∏ˆ"1"ΩÙ∏˙∆‰∫Û
            int j,k;
            for(j=0; j<=cnt; ++j) {
                flag[j+i] = 1;
            }
            for(j=j+i; j<n; ++j) {
                flag[j] = 0;    //‘Ÿ∞—cnt∏ˆ"1"∫Û√Êº”…œ"0"
            }
            for(j=0, k=0; j<n; ++j) {
                if (flag[j] != 0) {
                    matchs[k++] = &_pro.match[j];
                }
            }
            
            ret = calc_bet_dulp_2(ggidx, matchs, m);
            if (ret != 0) {
                return ret;
            }
            
        }
    }while(i > 0);
    
    return 0;
}

// ∞¥ÕÊ∑®◊ˆµ—ø®∂˚ª˝
int calc_bet_dulp_2(int ggidx, Match *match[MAX_MATCH], int size)
{
    Select **play[MAX_MATCH] = {0};
    int x[MAX_MATCH] = {0}, y=0, i, j, f, ret;
    
    // π˝¬Àµ®¬Î
    for(i=0, f=0; i<size; ++i){
        f += match[i]->fixed;
    }
    if (f != _pro.fixed_size  && f != size) {
        return 0;
    }
    
    while(1) {
        if (x[y] >= match[y]->play_size) {
            if (y == 0) {
                break;
            } else {
                x[y--] = 0;
                continue;
            }
        }
        
        if (y != size-1) {
            play[y] = match[y]->play[x[y]];
            x[y++]++;
            continue;
        }
        
        
        for(i=0; i<match[y]->play_size; ++i) {
            play[y] = match[y]->play[i];
            for(j=0; j<MAX_MATCH; ++j) {
                if (_pro.ggtype[ggidx].gg[j] == 0) {
                    continue;
                }
                ret = calc_bet_dulp_3(j+1, play, size);
                if (ret != 0) {
                    return ret;
                }
            }
        }
        
        if (size == 1) {
            break;
        }
        
        y--;
    }
    return 0;
}

// ∞¥π˝πÿ≥°¥Œ◊ˆ◊È∫œ
int calc_bet_dulp_3(int gg, Select **play[MAX_MATCH], int size)
{
    Select **play_c[MAX_MATCH] = {0};
    int n = size;
    int m = gg;
    int i, cnt=0, flag[MAX_MATCH] = {0}, ret;
    
    for(i=0; i<m; ++i) {
        flag[i] = 1;
        play_c[i] = play[i];
    }
    
    ret = calc_bet_dulp_4(play_c, m);
    if (ret != 0) {
        return ret;
    }
    
    do {
        cnt = 0;
        for(i=n-1; i>0; i--) {
            if (flag[i] == 0 && flag[i-1] == 1) { // …®√ËµΩ"10"
                break;
            }
            if (1 == flag[i]) {
                cnt++;  //Õ≥º∆1µƒ∏ˆ ˝
            }
        }
        if (i > 0) {
            int t = flag[i];
            flag[i] = flag[i-1];
            flag[i-1] = t;
            //”“±ﬂcnt∏ˆ"1"ΩÙ∏˙∆‰∫Û
            int j,k;
            for(j=0; j<=cnt; ++j) {
                flag[j+i] = 1;
            }
            for(j=j+i; j<n; ++j) {
                flag[j] = 0;    //‘Ÿ∞—cnt∏ˆ"1"∫Û√Êº”…œ"0"
            }
            for(j=0, k=0; j<n; ++j) {
                if (flag[j] != 0) {
                    play_c[k++] = play[j];
                }
            }
            
            ret = calc_bet_dulp_4(play_c, m);;
            if (ret != 0) {
                return ret;
            }
            
        }
    }while(i > 0);
    
    return 0;
}

// ∂‘ÕÊ∑®◊È∫œ◊ˆµ—ø®∂˚ª˝£¨º∆À„≥ˆÀ˘”–◊¢ ˝
int calc_bet_dulp_4(Select **play[MAX_MATCH], int size)
{
    Select *sel[MAX_MATCH] = {0};
    int x[MAX_MATCH] = {0}, y=0, i, ret;
    while(1) {
        if (play[y][x[y]] == NULL) {
            if (y == 0) {
                break;
            } else {
                x[y--] = 0;
                continue;
            }
        }
        
        if (y != size-1) {
            sel[y] = play[y][x[y]];
            x[y++]++;
            continue;
        }
        
        
        for(i=0; play[y][i] != NULL; ++i) {
            sel[y] = play[y][i];
            //ret = add_bet(sel, size);
            ret = calc_bouns(sel, size);
            if (ret != 0) {
                return ret;
            }
        }
        
        if (size == 1) {
            break;
        }
        
        y--;
    }
    return 0;
}

// º∆À„Õ∂◊¢£¨≤ªø…÷ÿ∏¥
int calc_bet()
{
    int i, j, ret;
    
    // ’˚∫œπ˝πÿ∑Ω Ω£¨∑¿÷π”–÷ÿ∏¥µƒπ˝πÿ∑Ω Ω≥ˆœ÷
    int gg[MAX_MATCH] = {0};
    for(i=0; i<_pro.ggtype_size; ++i) {
        for(j=0; j<MAX_MATCH; ++j) {
            gg[j] |= _pro.ggtype[i].gg[j];
        }
    }
    
    for(i=0; i<MAX_MATCH; ++i) {
        if (gg[i] == 1) {
            ret = calc_bet_1(i+1);
            if (ret != 0) {
                return ret;
            }
        }
    }
    
    return 0;
}

// ∏˘æ›π˝πÿ≥°¥ŒΩ¯––◊È∫œ
int calc_bet_1(int gg)
{
    Match *matchs[MAX_MATCH] = {0};
    int n = _pro.match_size;
    int m = gg;
    int i, cnt=0, flag[MAX_MATCH] = {0}, ret;
    
    for(i=0; i<m; ++i) {
        flag[i] = 1;
        matchs[i] = &_pro.match[i];
    }
    
    ret = calc_bet_2(matchs, m);
    if (ret != 0) {
        return ret;
    }
    
    do {
        cnt = 0;
        for(i=n-1; i>0; i--) {
            if (flag[i] == 0 && flag[i-1] == 1) { // …®√ËµΩ"10"
                break;
            }
            if (1 == flag[i]) {
                cnt++;  //Õ≥º∆1µƒ∏ˆ ˝
            }
        }
        if (i > 0) {
            int t = flag[i];
            flag[i] = flag[i-1];
            flag[i-1] = t;
            //”“±ﬂcnt∏ˆ"1"ΩÙ∏˙∆‰∫Û
            int j,k;
            for(j=0; j<=cnt; ++j) {
                flag[j+i] = 1;
            }
            for(j=j+i; j<n; ++j) {
                flag[j] = 0;    //‘Ÿ∞—cnt∏ˆ"1"∫Û√Êº”…œ"0"
            }
            for(j=0, k=0; j<n; ++j) {
                if (flag[j] != 0) {
                    matchs[k++] = &_pro.match[j];
                }
            }
            
            ret = calc_bet_2(matchs, m);
            if (ret != 0) {
                return ret;
            }
            
        }
    }while(i > 0);
    
    return 0;
}

// µ—ø®∂˚ª˝
int calc_bet_2(Match *match[MAX_MATCH], int size)
{
    Select *sel[MAX_MATCH] = {0};
    int x[MAX_MATCH] = {0}, y=0, i, f, ret;
    
    // π˝¬Àµ®¬Î
    for(i=0, f=0; i<size; ++i){
        f += match[i]->fixed;
    }
    if (f != _pro.fixed_size && f != size) {
        return 0;
    }
    
    while(1) {
        if (x[y] >= match[y]->sel_size) {
            if (y == 0) {
                break;
            } else {
                x[y--] = 0;
                continue;
            }
        }
        
        if (y != size-1) {
            sel[y] = &match[y]->sel[x[y]];
            x[y++]++;
            continue;
        }
        
        
        for(i=0; i<match[y]->sel_size; ++i) {
            sel[y] = &match[y]->sel[i];
            ret = calc_bouns(sel, size);
            if (ret != 0) {
                return ret;
            }
        }
        
        if (size == 1) {
            break;
        }
        
        y--;
    }
    return 0;
}


int calc_bouns(Select *sel[MAX_MATCH], int size)
{
    int i, c;
    double odds=1;
    
    for(i=0, c=0; i<size; ++i) {
        if (_bet.betlist != NULL) {
            strcat(_bet.betlist, sel[i]->raw);
            strcat(_bet.betlist, ";");
        }
        
        odds *= sel[i]->odds;
        c += sel[i]->ismax;
    }
    if (_bet.betlist != NULL) {
        _bet.betlist[strlen(_bet.betlist)-1] = '|';
    }
    
    // µ•πÿÕ∂◊¢£¨µ•◊¢◊Ó∏ﬂΩ±Ωœﬁ∂ÓŒ™500ÕÚ‘™£ª
    // 2ªÚ3≥°π˝πÿÕ∂◊¢£¨µ•◊¢◊Ó∏ﬂΩ±Ωœﬁ∂ÓŒ™20ÕÚ‘™£ª
    // 4ªÚ5≥°π˝πÿÕ∂◊¢£¨µ•◊¢◊Ó∏ﬂΩ±Ωœﬁ∂ÓŒ™50ÕÚ‘™£ª
    // 6≥°º∞“‘…œπ˝πÿÕ∂◊¢£¨µ•◊¢◊Ó∏ﬂΩ±Ωœﬁ∂Ó100ÕÚ‘™
    if (_pro.lot == LOT_JCZQ || _pro.lot == LOT_JCLQ) {
        switch(size){
            case 1:
                odds = odds >= 5000000/2 ? 5000000/2 : odds;
            case 2: case 3:
                odds = odds >= 200000/2 ? 200000/2 : odds;
            case 4: case 5:
                odds = odds >= 500000/2 ? 500000/2 : odds;
            case 6: case 7: case 8: default:
                odds = odds >= 1000000/2 ? 1000000/2 : odds;
        }
    }
    
    if (c == size) {
        _bet.max += odds;
    }
    
    if (_bet.min == 0 || odds < _bet.min) {
        _bet.min = odds;
    }
    
    ++_bet.betcnt;
    return 0;
}

int api_calc_bet(int lot, char *ggtype, char *content, int ismix, int isdupl, double *min, double *max, long *betcnt, char *betlist)
{
    int ret = 0;
    if (lot != LOT_JCZQ && lot != LOT_JCLQ && lot != LOT_BJDC) {
        return ERR_LOTTERY;
    }
    
    // ±±æ©µ•≥°≤ª÷ß≥÷ªÏÕ∂
    if (lot == LOT_BJDC && ismix == 1) {
        return ERR_LOTTERY;
    }
    
    memset(&_pro, 0x00, sizeof(Project));
    memset(&_bet, 0x00, sizeof(Bet));
    _bet.betlist = betlist;
    
    // Ω‚∞¸
    _pro.lot = lot;
    _pro.isdupl = isdupl;
    _pro.ismix = ismix;
    ret = unpack(ggtype, content);
    if (ret != 0) {
        return ret;
    }
    
    // º∆À„◊Ó¥Û≈‚¬ ◊È∫œ
    ret = calc_max_odds_comb();
    if (ret != 0) {
        return ret;
    }
    
    // ≤∑÷Õ∂◊¢ƒ⁄»›
    if (_pro.isdupl == 1) {
        ret = calc_bet_dupl();
    } else {
        ret = calc_bet();
    }
    if (ret != 0) {
        return ret;
    }
    
    *betcnt = _bet.betcnt;
    *min = _bet.min;
    *max = _bet.max;
    
    if (betlist != NULL) {
        betlist[strlen(betlist)-1] = '\0';
    }
    
    return 0;
}

void print_project()
{
    int i, j;
    printf("------------------------------ INFO ------------------------------\n");
    printf("LOTTERY: %d\n", _pro.lot);
    printf("FIXEDS: %d\n", _pro.fixed_size);
    printf("MATCHS: %d\n", _pro.match_size);
    printf("GGTYPE: ");
    for(i=0; i<_pro.ggtype_size; ++i) {
        printf("%s, ", _pro.ggtype[i].name);
    }
    printf("\n");
    
    printf("------------------------------ MATCH -------------------------------\n");
    for(i=0; i<_pro.match_size; ++i) {
        Match *match = &_pro.match[i];
        printf("ID:%s, FD:%d, EX:%0.2f, PLAYS:%d, SIZE:%d\n", match->id, match->fixed, match->extra_score, match->play_size, match->sel_size);
        for(j=0; j<match->sel_size; ++j) {
            Select *sel = &match->sel[j];
            printf("play:%d, odds:%0.2f, select:%d, home:%0.2f, away:%0.2f, max:%d, raw:%s\n",
                   sel->playid, sel->odds, sel->select, sel->home_score, sel->away_score,
                   sel->ismax, sel->raw);
        }
        printf("\n\n");
    }
}
